package com.uchiha.nova.mainService.filter;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.uchiha.nova.mainService.props.AuthProperties;
import com.uchiha.nova.mainService.props.AuthUtil;
import com.uchiha.nova.mainService.props.HeaderConstant;
import com.uchiha.nova.mainService.props.NovaUser;
import com.uchiha.nova.mainService.provider.AuthProvider;
import com.uchiha.nova.mainService.provider.GatewayUtil;
import com.uchiha.nova.mainService.provider.RequestProvider;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * @author 周林静
 * @Date 2022-12-31,0031 22:05
 * @Version 1.0
 */
@Slf4j
@Component
public class AuthFilterGatewayFilterFactory extends AbstractGatewayFilterFactory {
    AuthProperties authProperties;

    ObjectMapper objectMapper;

    RedisTemplate<String, Object> redisTemplate;

    @Override
    @SneakyThrows
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            //校验 Token 放行
    
            ApplicationContext applicationContext = exchange.getApplicationContext();
            if(applicationContext!=null&&applicationContext.getBean("authProperties")!=null&&authProperties==null) {
                authProperties= (AuthProperties) applicationContext.getBean("authProperties");
            }
            if (applicationContext != null && applicationContext.getBean("redisTemplate") != null && redisTemplate == null) {
                redisTemplate = (RedisTemplate<String, Object>) applicationContext.getBean("redisTemplate");
            }
            if (applicationContext != null && applicationContext.getBean("objectMapper") != null && objectMapper == null) {
                objectMapper = (ObjectMapper) applicationContext.getBean("objectMapper");
            }

            String originalRequestUrl = RequestProvider.getOriginalRequestUrl(exchange);
            int index1 = originalRequestUrl.indexOf("/");
            int index = originalRequestUrl.indexOf("/", index1 + 1);

            String path = exchange.getRequest().getURI().getPath();
            String service = originalRequestUrl.substring(0,index)+path;



            if(originalRequestUrl.contains("?")){
                String unUse = originalRequestUrl.substring(originalRequestUrl.indexOf("?"));
                originalRequestUrl = originalRequestUrl.replace(unUse,"");

            }
            if (GatewayUtil.isSkip(originalRequestUrl,authProperties)) {

                return chain.filter(exchange);
            }

            //校验 Token 合法性
            ServerHttpResponse resp = exchange.getResponse();
            String headerToken = exchange.getRequest().getHeaders().getFirst(AuthProvider.AUTH_KEY);

            if (StrUtil.isAllBlank(headerToken)) {
                return GatewayUtil.unAuth(resp, "缺失令牌,鉴权失败",objectMapper);
            }
            String accessToken = StrUtil.subAfter(headerToken,"Bearer ",false);

            if(!redisTemplate.hasKey("nova:oauth:token:"+accessToken)){
                return GatewayUtil.unAuth(resp, "无效的令牌",objectMapper);
            }


            NovaUser novaUser = AuthUtil.getUserByToken(accessToken);


            String userId = novaUser.getUserId().toString();

            String client_id = novaUser.getClientId().toString();
            String username = novaUser.getUserName();
            String TenantId = novaUser.getTenantId();
            String companyId = novaUser.getCompanyId();
            String postId = novaUser.getPostId();
            String deptId = novaUser.getDeptId();
            String[] roles = novaUser.getRoleName().split(",");
            String dataAuth = ObjectUtil.defaultIfEmpty(novaUser.getDataAuth(),"1");
            String role = roles[0];
//        if(!isRoleHasPer(service,role)){
//            return expressAuth(resp, "没有访问权限");
//        }

            ServerHttpRequest request = exchange.getRequest().mutate()
                    .header(AuthProvider.AUTH_KEY,headerToken)
                    .header(HeaderConstant.NOVA_CLIENT, client_id)
                    .header(HeaderConstant.NOVA_USER_ID, userId)
                    .header(HeaderConstant.NOVA_USERNAME, username)
                    .header(HeaderConstant.NOVA_USER_ROLE, role)
                    .header(HeaderConstant.NOVA_USER_POST, postId)
                    .header(HeaderConstant.NOVA_USER_DEPT, deptId)
                    .header(HeaderConstant.NOVA_USER_COMPANY, companyId)
                    .header(HeaderConstant.NOVA_USER_TENANT,TenantId)
                    .header(HeaderConstant.NOVA_DATA_AUTH,dataAuth)
                    .build();
            exchange = exchange.mutate().request(request).build();
            Long c = System.currentTimeMillis();

            return chain.filter(exchange);
        };
    }
}
